C# 调用Java的WebService的3种方式 您所在的位置:网站首页 java webservice接口开发及使用 C# 调用Java的WebService的3种方式

C# 调用Java的WebService的3种方式

2024-06-23 11:01| 来源: 网络整理| 查看: 265

 关于soapheader调用,可以参考

C#调用Java的WebService添加SOAPHeader验证

 

1.问题描述

调用的Java的webservice

string Invoke(string func, string reqXml)

 使用C#直接调用一直报错。

 

webservice提供方有说明如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 身份验证采用对SOAP身份认证(用户名/密码验证/序列号)的方式部署,设定用户名和密码由系统配置,所有文本内容编码选择UTF-8编码规范 [系统配置] [系统配置] [系统配置]

 

相信就是soapenv:Header这里的问题了,C# 没soapenv:Header这些东西的

 

网上查了好多类似下面的

https://www.cnblogs.com/o2ds/p/4093413.html

C#访问Java的WebService添加SOAPHeader验证的问题

都没有用

 

后来尝试sopui及xmlspy创建soap,直接发送xml,终于试出来了,然后C#使用http post调用webservice,成功了。

 

2.问题解决1

C#拼接的需要http post的soap字符串如下

照搬给的文档里的字符串 为调用函数,string Invoke(string func, string reqXml) 函数名Invoke,两个参数,自行理解吧

注意:里面的\r\n换行标志都要保留,不然都是报错

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 string soap = "\r\n" +                "\r\n" +                "\r\n" +                    "\r\n" +                        "xx\r\n" +                        "xxx\r\n" +                        "xxxx\r\n" +                    "\r\n" +                "\r\n" +                "\r\n" +                    "\r\n" +                        "" + jkid + "\r\n" +                        "" + HttpUtility.HtmlEncode(xml) + "\r\n" +                    "\r\n" +                "\r\n" +                "";

  然后发送,随便找个http post的代码就行了

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public static string GetSOAPReSource(string url, string datastr)        {            try            {                //request                Uri uri = new Uri(url);                WebRequest webRequest = WebRequest.Create(uri);                webRequest.ContentType = "text/xml; ";                  webRequest.Method = "POST";                using (Stream requestStream = webRequest.GetRequestStream())                {                    byte[] paramBytes = Encoding.UTF8.GetBytes(datastr.ToString());                    requestStream.Write(paramBytes, 0, paramBytes.Length);                }                //response                WebResponse webResponse = webRequest.GetResponse();                using (StreamReader myStreamReader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))                {                    string result = "";                    return result = myStreamReader.ReadToEnd();                }            }            catch (Exception ex)            {                throw ex;            }        }

  

3.问题解决2

发现还是报错,http 500错误,和之前不一样,但依然不对

研究webservice的wsdl发现了问题

 

调用时加上

1 webRequest.Headers.Add("SOAPAction", "http://tempuri.org/IAjsjService/Invoke");终于成功了

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public static string GetSOAPReSource(string url, string datastr)        {            try            {                //request                Uri uri = new Uri(url);                WebRequest webRequest = WebRequest.Create(uri);                webRequest.ContentType = "text/xml; charset=utf-8";                webRequest.Headers.Add("SOAPAction", "http://tempuri.org/IAjsjService/Invoke");                  webRequest.Method = "POST";                using (Stream requestStream = webRequest.GetRequestStream())                {                    byte[] paramBytes = Encoding.UTF8.GetBytes(datastr.ToString());                    requestStream.Write(paramBytes, 0, paramBytes.Length);                }                //response                WebResponse webResponse = webRequest.GetResponse();                using (StreamReader myStreamReader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))                {                    string result = "";                    return result = myStreamReader.ReadToEnd();                }            }            catch (Exception ex)            {                throw ex;            }        }

  

其他调用webservice的方式:

上一篇链接如上,更像是 Net下采用GET/POST/SOAP方式动态调用WebService的简易灵活方法(C#) 来处理xml,解决复杂的认证

 

又遇到一家

复制代码 身份验证采用对SOAP身份认证(用户名/密码验证/序列号)的方式部署,设定用户名和密码由系统配置,所有文本内容编码选择UTF-8编码规范 [系统配置] [系统配置] [系统配置] 复制代码

 

wsdl的xml如下

 

使用添加服务引用加到项目里

 

不要用高级那里的添加web引用添加,不然后面没法做

生成的Reference.cs如下

复制代码 //------------------------------------------------------------------------------ // // 此代码由工具生成。 // 运行时版本:4.0.30319.1026 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // //------------------------------------------------------------------------------ namespace v { [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ServiceModel.ServiceContractAttribute(ConfigurationName="V.IAjsjService")] public interface IAjsjService { [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAjsjService/Invoke", ReplyAction="http://tempuri.org/IAjsjService/InvokeResponse")] string Invoke(string func, string reqXml); } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public interface IAjsjServiceChannel : v.IAjsjService, System.ServiceModel.IClientChannel { } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public partial class AjsjServiceClient : System.ServiceModel.ClientBase, v.IAjsjService { public AjsjServiceClient() { } public AjsjServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public AjsjServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public AjsjServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public AjsjServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public string Invoke(string func, string reqXml) { return base.Channel.Invoke(func, reqXml); } } } 复制代码

 

调用方法:

定义soapheader

复制代码 public class MySoapHeader { string username;//用户名 string password;//密码 string serialNo;//序列号 public MySoapHeader() { } public MySoapHeader(string u, string p, string s) { Username = u; Password = p; SerialNo = s; } public string Username { get { return username; } set { username = value; } } public string Password { get { return password; } set { password = value; } } public string SerialNo { get { return serialNo; } set { serialNo = value; } } } 复制代码

调用

复制代码 MySoapHeader myHeader = new MySoapHeader(m_user, m_pw, m_serial); ServiceReference.AjsjServiceClient client = new ServiceReference.AjsjServiceClient("BasicHttpBinding_IAjsjService", m_serverUrl); using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) { MessageHeader header = MessageHeader.CreateHeader("Authentication", "http://ant.com", myHeader); OperationContext.Current.OutgoingMessageHeaders.Add(header); client.Invoke(func, strXml); 复制代码

 

 

1.直接调用

已知webservice路径,则可以直接 添加服务引用--高级--添加web引用 直接输入webservice URL。这个比较常见也很简单

即有完整的webservice文件目录如下图所示,

也可以在本地IIS根据webservice文件目录新发布一个webservice,然后程序动态调用,修改Url

1 public new string Url { set; get; }

 

 

2.根据wsdl文件生成webservice 的.cs文件 及 生成dll C#调用  

有时没有这么多文件,只有wsdl文件

wsdl文件可以有别人提供或者根据webservice地址获取:

http://localhost:8888/WS.asmx?wsdl

 

 

 

Visual Studio 2013->Visual Studio Tools->VS2013 开发人员命令提示

 

 

命令行输入

wsdl E:\WS.wsdl /out:WS.cs

  E:\WS.wsdl  是wsdl文件存储路径,也可以是http://localhost:8888/WS.asmx?wsdl   不报错的话,看路径下 Program Files\Microsoft Visual Studio 12.0\WS.cs已经自动生成   .cs文件看函数声明,结构体等都非常方便   然后命令行执行 csc /t:library WS.cs   同样的路径下,生成了WS.dll,拷贝出去放到项目文件夹下,C# winform程序也可以添加引用了。   生成的文件默认在这里:       默认生成的SOAP版本为1.1,可以

G:\Program Files\Microsoft Visual Studio 12.0>wsdl E:\e.wsdl /protocol:SOAP12 /out:e.cs

来指定1.2

   

3.C# 动态调用WebService  

在C#程序中,若要调用WebService,一般是采用"添加Web引用"的方式来实现的。但如果此WebService的URL是在程序运行过程中才能获得的,那怎么办呢?那就必须是"动态"调用这个WebService了。

  举个使用它的例子: object[] args = new object[1]; args.SetValue("cyy_JS", 0); DataTable dt = WebServiceHelper.InvokeWebService("http://192.168.0.10/DBMS_CYY/DBMS_Service.asmx", "GetUserTreeListData", args) as DataTable;

 

  恩~有点麻烦,这意味着每次我都要把想调用的函数的参数组织成一个object[]才行,且每次调用InvokeWebService都是在内存中创建动态程序集,效率极低。则次种方法绝对没有直接用“实例名.方法名(参数列表)”来的舒服。   我把它放到一个叫WebServiceHelper.cs的类里面了。   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 using System.IO; using System.Web.Services.Description; using Microsoft.CSharp; using System.CodeDom.Compiler; using System.CodeDom;    ///            /// 动态调用WebService           ///            /// WebService地址           /// 类名           /// 方法名(模块名)           /// 参数列表           /// object           public static object InvokeWebService(string url, string classname, string methodname, object[] args)          {              string @namespace = "ServiceBase.WebService.DynamicWebLoad";              if (classname == null || classname == "")              {                  classname = WebServiceHelper.GetClassName(url);              }              //获取服务描述语言(WSDL)               WebClient wc = new WebClient();              Stream stream = wc.OpenRead(url + "?WSDL");              ServiceDescription sd = ServiceDescription.Read(stream);              ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();              sdi.AddServiceDescription(sd, "", "");              CodeNamespace cn = new CodeNamespace(@namespace);              //生成客户端代理类代码               CodeCompileUnit ccu = new CodeCompileUnit();              ccu.Namespaces.Add(cn);              sdi.Import(cn, ccu);              CSharpCodeProvider csc = new CSharpCodeProvider();              ICodeCompiler icc = csc.CreateCompiler();              //设定编译器的参数               CompilerParameters cplist = new CompilerParameters();              cplist.GenerateExecutable = false;              cplist.GenerateInMemory = true;              cplist.ReferencedAssemblies.Add("System.dll");              cplist.ReferencedAssemblies.Add("System.XML.dll");              cplist.ReferencedAssemblies.Add("System.Web.Services.dll");              cplist.ReferencedAssemblies.Add("System.Data.dll");              //编译代理类               CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);              if (true == cr.Errors.HasErrors)              {                  System.Text.StringBuilder sb = new StringBuilder();                  foreach (CompilerError ce in cr.Errors)                  {                      sb.Append(ce.ToString());                      sb.Append(System.Environment.NewLine);                  }                  throw new Exception(sb.ToString());              }              //生成代理实例,并调用方法               System.Reflection.Assembly assembly = cr.CompiledAssembly;              Type t = assembly.GetType(@namespace + "." + classname, true, true);              object obj = Activator.CreateInstance(t);              System.Reflection.MethodInfo mi = t.GetMethod(methodname);              return mi.Invoke(obj, args);          }              private static string GetClassName(string url)          {              string[] parts = url.Split('/');              string[] pps = parts[parts.Length - 1].Split('.');              return pps[0];          } 

  

参考 http://blog.csdn.net/chuxiamuxiang/article/details/5731988

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有